package rabbitas{
	import rabbitas.ns.Nodes;
	import flash.utils.describeType;
	import rabbitas.attributes.AttributeName;
	/**
	 * @author martindyrby
	 */
	public class AutoWireManager{
		private var types:Object;
		public var instanceManager:InstanceManager;
		private var names:Array;
		private var _xmldata:XML;
		public function AutoWireManager(xmldata:XML){
			_xmldata = xmldata;
		}

		public function autoWireInstance(instance:*):void{
			if(types==null) { return;}
			var type:XML = describeType(instance);
			var accessor:XML;
			
			for(var typeName:String in types){
				for each(accessor in type.descendants("accessor").(@type==typeName&&@access!="readonly")){
					RabbitLogger.debug(typeName,"found in accessor",accessor.@name);
					instance[accessor.@name]=instanceManager.getObjectById(types[typeName]);
				}
				for each(accessor in type.descendants("variable").(@type==typeName)) {
					RabbitLogger.debug(typeName,"found in variable",accessor.@name);
					instance[accessor.@name]=instanceManager.getObjectById(types[typeName]);
				}
			}
			
			for(var i:int = 0; i < names.length;++i) {
				var nameStr:String = names[i];
				for each(accessor in type.descendants("accessor").(@name==name && @access!="readonly")) {
					RabbitLogger.debug(nameStr,"found in accessor",accessor.@name);
					instance[accessor.@name]=instanceManager.getObjectById(nameStr);
				}
				for each(accessor in type.descendants("variable").(@name==nameStr)) {
					RabbitLogger.debug(nameStr,"found in variable",accessor.@name);
					instance[accessor.@name]=instanceManager.getObjectById(nameStr);
				}

			}
		}

		public function resolveAutoWireDefinitions():void{
			types=new Object();
			names = new Array();
			names.push("root");
			for each(var autoWireChild:XML in _xmldata.descendants(Nodes.objectQName).(hasOwnProperty("@"+AttributeName.AUTO_WIRE_BY))){
				var typeString:String = autoWireChild.@[AttributeName.AUTO_WIRE_BY];
				switch(typeString) {
					case 'type':
						var aliasName:String=Reflector.reflectStringValue(autoWireChild.@[AttributeName.TYPE],instanceManager);
						var parts:Array=aliasName.split(".");
						var className:String=parts.pop();
						if(parts.length>0){
							aliasName=parts.join(".")+"::"+className;
						} else {
							aliasName=className;
						}
						types[aliasName]=autoWireChild.@[AttributeName.ID];
						break;
					case 'name':
						names.push(autoWireChild.@[AttributeName.ID]);
						break;
				}
			}
		}
	}
}
